﻿using System;
using FortuneUniverse.Fortune.Algorithms;

namespace FortuneUniverse.Fortune.Dyson
{
  public class SimplexNoise
  {
    private static SimplexNoise.Grad[] grad3 = new SimplexNoise.Grad[12]
    {
      new SimplexNoise.Grad(1.0, 1.0, 0.0),
      new SimplexNoise.Grad(-1.0, 1.0, 0.0),
      new SimplexNoise.Grad(1.0, -1.0, 0.0),
      new SimplexNoise.Grad(-1.0, -1.0, 0.0),
      new SimplexNoise.Grad(1.0, 0.0, 1.0),
      new SimplexNoise.Grad(-1.0, 0.0, 1.0),
      new SimplexNoise.Grad(1.0, 0.0, -1.0),
      new SimplexNoise.Grad(-1.0, 0.0, -1.0),
      new SimplexNoise.Grad(0.0, 1.0, 1.0),
      new SimplexNoise.Grad(0.0, -1.0, 1.0),
      new SimplexNoise.Grad(0.0, 1.0, -1.0),
      new SimplexNoise.Grad(0.0, -1.0, -1.0)
    };
    private static SimplexNoise.Grad[] grad4 = new SimplexNoise.Grad[32]
    {
      new SimplexNoise.Grad(0.0, 1.0, 1.0, 1.0),
      new SimplexNoise.Grad(0.0, 1.0, 1.0, -1.0),
      new SimplexNoise.Grad(0.0, 1.0, -1.0, 1.0),
      new SimplexNoise.Grad(0.0, 1.0, -1.0, -1.0),
      new SimplexNoise.Grad(0.0, -1.0, 1.0, 1.0),
      new SimplexNoise.Grad(0.0, -1.0, 1.0, -1.0),
      new SimplexNoise.Grad(0.0, -1.0, -1.0, 1.0),
      new SimplexNoise.Grad(0.0, -1.0, -1.0, -1.0),
      new SimplexNoise.Grad(1.0, 0.0, 1.0, 1.0),
      new SimplexNoise.Grad(1.0, 0.0, 1.0, -1.0),
      new SimplexNoise.Grad(1.0, 0.0, -1.0, 1.0),
      new SimplexNoise.Grad(1.0, 0.0, -1.0, -1.0),
      new SimplexNoise.Grad(-1.0, 0.0, 1.0, 1.0),
      new SimplexNoise.Grad(-1.0, 0.0, 1.0, -1.0),
      new SimplexNoise.Grad(-1.0, 0.0, -1.0, 1.0),
      new SimplexNoise.Grad(-1.0, 0.0, -1.0, -1.0),
      new SimplexNoise.Grad(1.0, 1.0, 0.0, 1.0),
      new SimplexNoise.Grad(1.0, 1.0, 0.0, -1.0),
      new SimplexNoise.Grad(1.0, -1.0, 0.0, 1.0),
      new SimplexNoise.Grad(1.0, -1.0, 0.0, -1.0),
      new SimplexNoise.Grad(-1.0, 1.0, 0.0, 1.0),
      new SimplexNoise.Grad(-1.0, 1.0, 0.0, -1.0),
      new SimplexNoise.Grad(-1.0, -1.0, 0.0, 1.0),
      new SimplexNoise.Grad(-1.0, -1.0, 0.0, -1.0),
      new SimplexNoise.Grad(1.0, 1.0, 1.0, 0.0),
      new SimplexNoise.Grad(1.0, 1.0, -1.0, 0.0),
      new SimplexNoise.Grad(1.0, -1.0, 1.0, 0.0),
      new SimplexNoise.Grad(1.0, -1.0, -1.0, 0.0),
      new SimplexNoise.Grad(-1.0, 1.0, 1.0, 0.0),
      new SimplexNoise.Grad(-1.0, 1.0, -1.0, 0.0),
      new SimplexNoise.Grad(-1.0, -1.0, 1.0, 0.0),
      new SimplexNoise.Grad(-1.0, -1.0, -1.0, 0.0)
    };
    public static short[] p = new short[256]
    {
      (short) 151,
      (short) 160,
      (short) 137,
      (short) 91,
      (short) 90,
      (short) 15,
      (short) 131,
      (short) 13,
      (short) 201,
      (short) 95,
      (short) 96,
      (short) 53,
      (short) 194,
      (short) 233,
      (short) 7,
      (short) 225,
      (short) 140,
      (short) 36,
      (short) 103,
      (short) 30,
      (short) 69,
      (short) 142,
      (short) 8,
      (short) 99,
      (short) 37,
      (short) 240,
      (short) 21,
      (short) 10,
      (short) 23,
      (short) 190,
      (short) 6,
      (short) 148,
      (short) 247,
      (short) 120,
      (short) 234,
      (short) 75,
      (short) 0,
      (short) 26,
      (short) 197,
      (short) 62,
      (short) 94,
      (short) 252,
      (short) 219,
      (short) 203,
      (short) 117,
      (short) 35,
      (short) 11,
      (short) 32,
      (short) 57,
      (short) 177,
      (short) 33,
      (short) 88,
      (short) 237,
      (short) 149,
      (short) 56,
      (short) 87,
      (short) 174,
      (short) 20,
      (short) 125,
      (short) 136,
      (short) 171,
      (short) 168,
      (short) 68,
      (short) 175,
      (short) 74,
      (short) 165,
      (short) 71,
      (short) 134,
      (short) 139,
      (short) 48,
      (short) 27,
      (short) 166,
      (short) 77,
      (short) 146,
      (short) 158,
      (short) 231,
      (short) 83,
      (short) 111,
      (short) 229,
      (short) 122,
      (short) 60,
      (short) 211,
      (short) 133,
      (short) 230,
      (short) 220,
      (short) 105,
      (short) 92,
      (short) 41,
      (short) 55,
      (short) 46,
      (short) 245,
      (short) 40,
      (short) 244,
      (short) 102,
      (short) 143,
      (short) 54,
      (short) 65,
      (short) 25,
      (short) 63,
      (short) 161,
      (short) 1,
      (short) 216,
      (short) 80,
      (short) 73,
      (short) 209,
      (short) 76,
      (short) 132,
      (short) 187,
      (short) 208,
      (short) 89,
      (short) 18,
      (short) 169,
      (short) 200,
      (short) 196,
      (short) 135,
      (short) 130,
      (short) 116,
      (short) 188,
      (short) 159,
      (short) 86,
      (short) 164,
      (short) 100,
      (short) 109,
      (short) 198,
      (short) 173,
      (short) 186,
      (short) 3,
      (short) 64,
      (short) 52,
      (short) 217,
      (short) 226,
      (short) 250,
      (short) 124,
      (short) 123,
      (short) 5,
      (short) 202,
      (short) 38,
      (short) 147,
      (short) 118,
      (short) 126,
      (short) byte.MaxValue,
      (short) 82,
      (short) 85,
      (short) 212,
      (short) 207,
      (short) 206,
      (short) 59,
      (short) 227,
      (short) 47,
      (short) 16,
      (short) 58,
      (short) 17,
      (short) 182,
      (short) 189,
      (short) 28,
      (short) 42,
      (short) 223,
      (short) 183,
      (short) 170,
      (short) 213,
      (short) 119,
      (short) 248,
      (short) 152,
      (short) 2,
      (short) 44,
      (short) 154,
      (short) 163,
      (short) 70,
      (short) 221,
      (short) 153,
      (short) 101,
      (short) 155,
      (short) 167,
      (short) 43,
      (short) 172,
      (short) 9,
      (short) 129,
      (short) 22,
      (short) 39,
      (short) 253,
      (short) 19,
      (short) 98,
      (short) 108,
      (short) 110,
      (short) 79,
      (short) 113,
      (short) 224,
      (short) 232,
      (short) 178,
      (short) 185,
      (short) 112,
      (short) 104,
      (short) 218,
      (short) 246,
      (short) 97,
      (short) 228,
      (short) 251,
      (short) 34,
      (short) 242,
      (short) 193,
      (short) 238,
      (short) 210,
      (short) 144,
      (short) 12,
      (short) 191,
      (short) 179,
      (short) 162,
      (short) 241,
      (short) 81,
      (short) 51,
      (short) 145,
      (short) 235,
      (short) 249,
      (short) 14,
      (short) 239,
      (short) 107,
      (short) 49,
      (short) 192,
      (short) 214,
      (short) 31,
      (short) 181,
      (short) 199,
      (short) 106,
      (short) 157,
      (short) 184,
      (short) 84,
      (short) 204,
      (short) 176,
      (short) 115,
      (short) 121,
      (short) 50,
      (short) 45,
      (short) sbyte.MaxValue,
      (short) 4,
      (short) 150,
      (short) 254,
      (short) 138,
      (short) 236,
      (short) 205,
      (short) 93,
      (short) 222,
      (short) 114,
      (short) 67,
      (short) 29,
      (short) 24,
      (short) 72,
      (short) 243,
      (short) 141,
      (short) 128,
      (short) 195,
      (short) 78,
      (short) 66,
      (short) 215,
      (short) 61,
      (short) 156,
      (short) 180
    };
    private static double F2 = 0.5 * (Math.Sqrt(3.0) - 1.0);
    private static double G2 = (3.0 - Math.Sqrt(3.0)) / 6.0;
    private static double F3 = 1.0 / 3.0;
    private static double G3 = 1.0 / 6.0;
    private static double F4 = (Math.Sqrt(5.0) - 1.0) / 4.0;
    private static double G4 = (5.0 - Math.Sqrt(5.0)) / 20.0;
    public short[] perm = new short[512];
    public short[] permMod12 = new short[512];

    public SimplexNoise(int seed) => this.InitMember(seed);

    private static int fastfloor(double x)
    {
      int num = (int) x;
      return x < (double) num ? num - 1 : num;
    }

    private static double dot(SimplexNoise.Grad g, double x, double y) => g.x * x + g.y * y;

    private static double dot(SimplexNoise.Grad g, double x, double y, double z) => g.x * x + g.y * y + g.z * z;

    private static double dot(SimplexNoise.Grad g, double x, double y, double z, double w) => g.x * x + g.y * y + g.z * z + g.w * w;

    private void InitMember(int seed)
    {
      short[] numArray = new short[256];
      URandom1 urandom1 = new URandom1(seed);
      for (int index = 0; index < 256; ++index)
        numArray[index] = (short) index;
      for (int index1 = 0; index1 < 256; ++index1)
      {
        int index2 = urandom1.Next(0, 256);
        int num = (int) numArray[index1];
        numArray[index1] = numArray[index2];
        numArray[index2] = (short) num;
      }
      for (int index = 0; index < 512; ++index)
      {
        this.perm[index] = numArray[index & (int) byte.MaxValue];
        this.permMod12[index] = (short) ((int) this.perm[index] % 12);
      }
    }

    public double Noise(double xin)
    {
      int num1 = SimplexNoise.fastfloor(xin);
      int num2 = num1 + 1;
      double num3 = xin - (double) num1;
      double num4 = num3 - 1.0;
      double num5 = 1.0 - num3 * num3;
      double num6 = num5 * num5;
      double num7 = num6 * num6 * SimplexNoise.grad3[(int) this.perm[num1 & (int) byte.MaxValue] & 7].x * num3;
      double num8 = 1.0 - num4 * num4;
      double num9 = num8 * num8;
      double num10 = num9 * num9 * SimplexNoise.grad3[(int) this.perm[num2 & (int) byte.MaxValue] & 7].x * num4;
      return (num7 + num10) * (256.0 / 81.0);
    }

    public double Noise(double xin, double yin)
    {
      double num1 = (xin + yin) * SimplexNoise.F2;
      int num2 = SimplexNoise.fastfloor(xin + num1);
      int num3 = SimplexNoise.fastfloor(yin + num1);
      double num4 = (double) (num2 + num3) * SimplexNoise.G2;
      double num5 = (double) num2 - num4;
      double num6 = (double) num3 - num4;
      double x1 = xin - num5;
      double y1 = yin - num6;
      int num7;
      int num8;
      if (x1 > y1)
      {
        num7 = 1;
        num8 = 0;
      }
      else
      {
        num7 = 0;
        num8 = 1;
      }
      double x2 = x1 - (double) num7 + SimplexNoise.G2;
      double y2 = y1 - (double) num8 + SimplexNoise.G2;
      double x3 = x1 - 1.0 + 2.0 * SimplexNoise.G2;
      double y3 = y1 - 1.0 + 2.0 * SimplexNoise.G2;
      int num9 = num2 & (int) byte.MaxValue;
      int index1 = num3 & (int) byte.MaxValue;
      int index2 = (int) this.permMod12[num9 + (int) this.perm[index1]];
      int index3 = (int) this.permMod12[num9 + num7 + (int) this.perm[index1 + num8]];
      int index4 = (int) this.permMod12[num9 + 1 + (int) this.perm[index1 + 1]];
      double num10 = 0.5 - x1 * x1 - y1 * y1;
      double num11;
      if (num10 < 0.0)
      {
        num11 = 0.0;
      }
      else
      {
        double num12 = num10 * num10;
        num11 = num12 * num12 * SimplexNoise.dot(SimplexNoise.grad3[index2], x1, y1);
      }
      double num13 = 0.5 - x2 * x2 - y2 * y2;
      double num14;
      if (num13 < 0.0)
      {
        num14 = 0.0;
      }
      else
      {
        double num15 = num13 * num13;
        num14 = num15 * num15 * SimplexNoise.dot(SimplexNoise.grad3[index3], x2, y2);
      }
      double num16 = 0.5 - x3 * x3 - y3 * y3;
      double num17;
      if (num16 < 0.0)
      {
        num17 = 0.0;
      }
      else
      {
        double num18 = num16 * num16;
        num17 = num18 * num18 * SimplexNoise.dot(SimplexNoise.grad3[index4], x3, y3);
      }
      return 70.1475 * (num11 + num14 + num17);
    }

    public double Noise(double xin, double yin, double zin)
    {
      double num1 = (xin + yin + zin) * SimplexNoise.F3;
      int num2 = SimplexNoise.fastfloor(xin + num1);
      int num3 = SimplexNoise.fastfloor(yin + num1);
      int num4 = SimplexNoise.fastfloor(zin + num1);
      double num5 = (double) (num2 + num3 + num4) * SimplexNoise.G3;
      double num6 = (double) num2 - num5;
      double num7 = (double) num3 - num5;
      double num8 = (double) num4 - num5;
      double x1 = xin - num6;
      double y1 = yin - num7;
      double z1 = zin - num8;
      int num9;
      int num10;
      int num11;
      int num12;
      int num13;
      int num14;
      if (x1 >= y1)
      {
        if (y1 >= z1)
        {
          num9 = 1;
          num10 = 0;
          num11 = 0;
          num12 = 1;
          num13 = 1;
          num14 = 0;
        }
        else if (x1 >= z1)
        {
          num9 = 1;
          num10 = 0;
          num11 = 0;
          num12 = 1;
          num13 = 0;
          num14 = 1;
        }
        else
        {
          num9 = 0;
          num10 = 0;
          num11 = 1;
          num12 = 1;
          num13 = 0;
          num14 = 1;
        }
      }
      else if (y1 < z1)
      {
        num9 = 0;
        num10 = 0;
        num11 = 1;
        num12 = 0;
        num13 = 1;
        num14 = 1;
      }
      else if (x1 < z1)
      {
        num9 = 0;
        num10 = 1;
        num11 = 0;
        num12 = 0;
        num13 = 1;
        num14 = 1;
      }
      else
      {
        num9 = 0;
        num10 = 1;
        num11 = 0;
        num12 = 1;
        num13 = 1;
        num14 = 0;
      }
      double x2 = x1 - (double) num9 + SimplexNoise.G3;
      double y2 = y1 - (double) num10 + SimplexNoise.G3;
      double z2 = z1 - (double) num11 + SimplexNoise.G3;
      double x3 = x1 - (double) num12 + 2.0 * SimplexNoise.G3;
      double y3 = y1 - (double) num13 + 2.0 * SimplexNoise.G3;
      double z3 = z1 - (double) num14 + 2.0 * SimplexNoise.G3;
      double x4 = x1 - 1.0 + 3.0 * SimplexNoise.G3;
      double y4 = y1 - 1.0 + 3.0 * SimplexNoise.G3;
      double z4 = z1 - 1.0 + 3.0 * SimplexNoise.G3;
      int num15 = num2 & (int) byte.MaxValue;
      int num16 = num3 & (int) byte.MaxValue;
      int index1 = num4 & (int) byte.MaxValue;
      int index2 = (int) this.permMod12[num15 + (int) this.perm[num16 + (int) this.perm[index1]]];
      int index3 = (int) this.permMod12[num15 + num9 + (int) this.perm[num16 + num10 + (int) this.perm[index1 + num11]]];
      int index4 = (int) this.permMod12[num15 + num12 + (int) this.perm[num16 + num13 + (int) this.perm[index1 + num14]]];
      int index5 = (int) this.permMod12[num15 + 1 + (int) this.perm[num16 + 1 + (int) this.perm[index1 + 1]]];
      double num17 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
      double num18;
      if (num17 < 0.0)
      {
        num18 = 0.0;
      }
      else
      {
        double num19 = num17 * num17;
        num18 = num19 * num19 * SimplexNoise.dot(SimplexNoise.grad3[index2], x1, y1, z1);
      }
      double num20 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
      double num21;
      if (num20 < 0.0)
      {
        num21 = 0.0;
      }
      else
      {
        double num22 = num20 * num20;
        num21 = num22 * num22 * SimplexNoise.dot(SimplexNoise.grad3[index3], x2, y2, z2);
      }
      double num23 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
      double num24;
      if (num23 < 0.0)
      {
        num24 = 0.0;
      }
      else
      {
        double num25 = num23 * num23;
        num24 = num25 * num25 * SimplexNoise.dot(SimplexNoise.grad3[index4], x3, y3, z3);
      }
      double num26 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4;
      double num27;
      if (num26 < 0.0)
      {
        num27 = 0.0;
      }
      else
      {
        double num28 = num26 * num26;
        num27 = num28 * num28 * SimplexNoise.dot(SimplexNoise.grad3[index5], x4, y4, z4);
      }
      return 32.696434 * (num18 + num21 + num24 + num27);
    }

    public double Noise(double x, double y, double z, double w)
    {
      double num1 = (x + y + z + w) * SimplexNoise.F4;
      int num2 = SimplexNoise.fastfloor(x + num1);
      int num3 = SimplexNoise.fastfloor(y + num1);
      int num4 = SimplexNoise.fastfloor(z + num1);
      int num5 = SimplexNoise.fastfloor(w + num1);
      double num6 = (double) (num2 + num3 + num4 + num5) * SimplexNoise.G4;
      double num7 = (double) num2 - num6;
      double num8 = (double) num3 - num6;
      double num9 = (double) num4 - num6;
      double num10 = (double) num5 - num6;
      double x1 = x - num7;
      double y1 = y - num8;
      double z1 = z - num9;
      double w1 = w - num10;
      int num11 = 0;
      int num12 = 0;
      int num13 = 0;
      int num14 = 0;
      if (x1 > y1)
        ++num11;
      else
        ++num12;
      if (x1 > z1)
        ++num11;
      else
        ++num13;
      if (x1 > w1)
        ++num11;
      else
        ++num14;
      if (y1 > z1)
        ++num12;
      else
        ++num13;
      if (y1 > w1)
        ++num12;
      else
        ++num14;
      if (z1 > w1)
        ++num13;
      else
        ++num14;
      int num15 = num11 < 3 ? 0 : 1;
      int num16 = num12 < 3 ? 0 : 1;
      int num17 = num13 < 3 ? 0 : 1;
      int num18 = num14 < 3 ? 0 : 1;
      int num19 = num11 < 2 ? 0 : 1;
      int num20 = num12 < 2 ? 0 : 1;
      int num21 = num13 < 2 ? 0 : 1;
      int num22 = num14 < 2 ? 0 : 1;
      int num23 = num11 < 1 ? 0 : 1;
      int num24 = num12 < 1 ? 0 : 1;
      int num25 = num13 < 1 ? 0 : 1;
      int num26 = num14 < 1 ? 0 : 1;
      double x2 = x1 - (double) num15 + SimplexNoise.G4;
      double y2 = y1 - (double) num16 + SimplexNoise.G4;
      double z2 = z1 - (double) num17 + SimplexNoise.G4;
      double w2 = w1 - (double) num18 + SimplexNoise.G4;
      double x3 = x1 - (double) num19 + 2.0 * SimplexNoise.G4;
      double y3 = y1 - (double) num20 + 2.0 * SimplexNoise.G4;
      double z3 = z1 - (double) num21 + 2.0 * SimplexNoise.G4;
      double w3 = w1 - (double) num22 + 2.0 * SimplexNoise.G4;
      double x4 = x1 - (double) num23 + 3.0 * SimplexNoise.G4;
      double y4 = y1 - (double) num24 + 3.0 * SimplexNoise.G4;
      double z4 = z1 - (double) num25 + 3.0 * SimplexNoise.G4;
      double w4 = w1 - (double) num26 + 3.0 * SimplexNoise.G4;
      double x5 = x1 - 1.0 + 4.0 * SimplexNoise.G4;
      double y5 = y1 - 1.0 + 4.0 * SimplexNoise.G4;
      double z5 = z1 - 1.0 + 4.0 * SimplexNoise.G4;
      double w5 = w1 - 1.0 + 4.0 * SimplexNoise.G4;
      int num27 = num2 & (int) byte.MaxValue;
      int num28 = num3 & (int) byte.MaxValue;
      int num29 = num4 & (int) byte.MaxValue;
      int index1 = num5 & (int) byte.MaxValue;
      int index2 = (int) this.perm[num27 + (int) this.perm[num28 + (int) this.perm[num29 + (int) this.perm[index1]]]] % 32;
      int index3 = (int) this.perm[num27 + num15 + (int) this.perm[num28 + num16 + (int) this.perm[num29 + num17 + (int) this.perm[index1 + num18]]]] % 32;
      int index4 = (int) this.perm[num27 + num19 + (int) this.perm[num28 + num20 + (int) this.perm[num29 + num21 + (int) this.perm[index1 + num22]]]] % 32;
      int index5 = (int) this.perm[num27 + num23 + (int) this.perm[num28 + num24 + (int) this.perm[num29 + num25 + (int) this.perm[index1 + num26]]]] % 32;
      int index6 = (int) this.perm[num27 + 1 + (int) this.perm[num28 + 1 + (int) this.perm[num29 + 1 + (int) this.perm[index1 + 1]]]] % 32;
      double num30 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
      double num31;
      if (num30 < 0.0)
      {
        num31 = 0.0;
      }
      else
      {
        double num32 = num30 * num30;
        num31 = num32 * num32 * SimplexNoise.dot(SimplexNoise.grad4[index2], x1, y1, z1, w1);
      }
      double num33 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
      double num34;
      if (num33 < 0.0)
      {
        num34 = 0.0;
      }
      else
      {
        double num35 = num33 * num33;
        num34 = num35 * num35 * SimplexNoise.dot(SimplexNoise.grad4[index3], x2, y2, z2, w2);
      }
      double num36 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
      double num37;
      if (num36 < 0.0)
      {
        num37 = 0.0;
      }
      else
      {
        double num38 = num36 * num36;
        num37 = num38 * num38 * SimplexNoise.dot(SimplexNoise.grad4[index4], x3, y3, z3, w3);
      }
      double num39 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
      double num40;
      if (num39 < 0.0)
      {
        num40 = 0.0;
      }
      else
      {
        double num41 = num39 * num39;
        num40 = num41 * num41 * SimplexNoise.dot(SimplexNoise.grad4[index5], x4, y4, z4, w4);
      }
      double num42 = 0.6 - x5 * x5 - y5 * y5 - z5 * z5 - w5 * w5;
      double num43;
      if (num42 < 0.0)
      {
        num43 = 0.0;
      }
      else
      {
        double num44 = num42 * num42;
        num43 = num44 * num44 * SimplexNoise.dot(SimplexNoise.grad4[index6], x5, y5, z5, w5);
      }
      return 27.29 * (num31 + num34 + num37 + num40 + num43);
    }

    public double Noise2DFBM(double x, double y, int nOctaves, double deltaAmp = 0.5, double deltaWLen = 2.0)
    {
      double num1 = 0.0;
      double num2 = 0.5;
      for (int index = 0; index < nOctaves; ++index)
      {
        num1 += this.Noise(x, y) * num2;
        num2 *= deltaAmp;
        x *= deltaWLen;
        y *= deltaWLen;
      }
      return num1;
    }

    public double Noise3DFBM(
      double x,
      double y,
      double z,
      int nOctaves,
      double deltaAmp = 0.5,
      double deltaWLen = 2.0)
    {
      double num1 = 0.0;
      double num2 = 0.5;
      for (int index = 0; index < nOctaves; ++index)
      {
        num1 += this.Noise(x, y, z) * num2;
        num2 *= deltaAmp;
        x *= deltaWLen;
        y *= deltaWLen;
        z *= deltaWLen;
      }
      return num1;
    }

    public class Grad
    {
      public double x;
      public double y;
      public double z;
      public double w;

      public Grad(double x, double y, double z)
      {
        this.x = x;
        this.y = y;
        this.z = z;
      }

      public Grad(double x, double y, double z, double w)
      {
        this.x = x;
        this.y = y;
        this.z = z;
        this.w = w;
      }
    }
  }
}
